#include<iostream>

// RAII ： Resource access is initialized  资源获取 即 初始化
// 资源的获取和释放    和     对象的生命周期  绑定


// 浅拷贝问题：类的成员中有指针变量，采用RAII机制，

// 但是拷贝时只拷贝了指针的值，导致两个指针指向同一个对上空间
// 释放时 导致了二次释放问题



// 深度拷贝：不能简单的拷贝指针成员，而是复制堆上空间


class Test
{
    public:
    // 类内只留下声明
        Test();
        
        
        Test(const Test& t);

        Test(int a);

        Test copy();

        void operator=(const Test&t);

        void SetValue(int n);

        void Print();

        ~Test();

    private:
    int *a;
};


// this指针：每个类都会带的，指向当前的对象一个指针
Test::Test()
{
   this->a = new int;
}


Test::Test(const Test &t)
{
    a = new int;
    *a = *t.a;  //  从拷贝指针  变成  拷贝  指向指向的空间的值，就不会出现二次释放的问题
}   
// this 指针 可以判断，到底是谁的成员（如果你没有，正常情况下编译器会帮你写好）


//用this 指针 去区分形参变量和 成员变量
Test::Test(int a)
{
    this->a = new int;
    *this->a = a;
}

Test Test::copy()
{
    return *this;//  *this ：当前对象
}

void Test::operator=(const Test &t)
{
    *a = *t.a;
}

void Test::SetValue(int n)
{
    *a = n;
}

void Test::Print()
{
    std::cout<<*a<<std::endl;
}

Test::~Test()
{
    delete a;
}

// int main()
// {
//     Test t;
//     t.SetValue(10);
//     t.Print();
// }

// int main()
// {
//     Test t;
//     Test t1(t); //  二次释放问题： 第一个t 里的指针a 在堆上申请空间，  
//     // 拷贝的时候把指针拷过去了，导致两个类的指针指向了同一个堆上空间，释放时会重复释放同一个堆上空间 
    
//     return 0;
// }

int main()
{
    Test t;
    Test t1;
    t = t1;
    return 0;
}